package org.example.reentrantlock;

import lombok.extern.slf4j.Slf4j;
import org.example.utils.Sleeper;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhengdp
 * @Description 条件变量 使用案例
 * @Date 2022/11/5 23:06
 * @Created by zhengdp
 */
@Slf4j(topic = "c.ConditionExampleTest")
public class ConditionExampleTest {

    static boolean hasCigarette = false ; // 有没有烟
    static boolean hasTakeout = false;

    private static ReentrantLock ROOM = new ReentrantLock();

    private static Condition waitCigaretteRoom = ROOM.newCondition();
    private static Condition waitTakeoutRoom = ROOM.newCondition();

    public static void main(String[] args) {
        new Thread(() -> {
            ROOM.lock();
            try{
                log.info("有烟没？ [{}]",hasCigarette);
                while(!hasCigarette){
                    log.info("没有烟，不干了，先歇会 ！");
                    try {
                        waitCigaretteRoom.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                log.info("再问一次，有烟没？ [{}]",hasCigarette);
                if(hasCigarette){
                    log.info("可以开始干活了");
                }else{
                    log.info("还没有烟，不干了走了。");
                }
            }finally {
                ROOM.unlock();
            }
        },"小南").start();

        new Thread(() -> {
            ROOM.lock();
            try{
                log.info("外卖送到没？ [{}]",hasTakeout);
                while(!hasTakeout){
                    log.info("没有外卖，睡觉！");
                    try {
                        waitTakeoutRoom.await();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                log.info("再问一次，外卖送到没？ [{}]",hasTakeout);
                if(hasTakeout){
                    log.info("可以开始干活了");
                }else{
                    log.info("外卖还没送到，走了");
                }
            }finally {
                ROOM.unlock();
            }
        },"小北").start();



        Sleeper.sleep(1000);

        new Thread(() -> {
            ROOM.lock();
            try{
                hasTakeout = true;
                log.info("外卖送到了奥");
                // 唤醒等待外卖的
                waitTakeoutRoom.signal();
            }finally {
                ROOM.unlock();
            }
        },"送外卖的人").start();

        new Thread(() -> {
            ROOM.lock();
            try{
                hasCigarette = true;
                log.info("烟送到了奥");
                // 唤醒等待烟的
                waitCigaretteRoom.signal();
            }finally {
                ROOM.unlock();
            }
        },"送烟的人").start();


    }
}
